home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / bbs / citsrc6K05.lha / old_sysdep1.c < prev    next >
C/C++ Source or Header  |  1996-08-29  |  37KB  |  1,201 lines

  1. /************************************************************************/
  2. /*                              sysdep1.c                               */
  3. /*                                                                      */
  4. /*      This is the repository of most of the system dependent code     */
  5. /*      in Citadel.  We hope, pray, and proselytize, at least.          */
  6. /************************************************************************/
  7. /************************************************************************/
  8. /*                              history                                 */
  9. /*                                                                      */
  10. /* 89Oct16 AP   Amiga                                                   */
  11. /* 87Apr01 HAW  File tagging completed; bug for .RD/.RE fixed.          */
  12. /* 86Dec14 HAW  Reorganized into areas.                                 */
  13. /* 86Nov25 HAW  Created.                                                */
  14. /************************************************************************/
  15. #define SYSTEM_DEPENDENT
  16. #define TIMER_FUNCTIONS_NEEDED
  17. #include "ctdl.h"
  18. #include "dos.h"
  19. #include "time.h"
  20. #include "string.h"
  21. #include "stdarg.h"
  22. /************************************************************************/
  23. /*                              Contents                                */
  24. /*                                                                      */
  25. /*              AREAS:                                                  */
  26. /*      bigDirectory()          gets an "extended" directory            */
  27. /* #    bigDirs()               work function for bigDirectory()        */
  28. /*      CitGetFileList()        gets list of files                      */
  29. /*      freeFileList()          Free file list                          */
  30. /*      getArea()               get an area from the sysop              */
  31. /*      goodArea()              get good area                           */
  32. /*      homeSpace()             takes us to our home space              */
  33. /*      netGetArea()            get area for dumping networked file(s)  */
  34. /*      netSetNewArea()         set area for dumping networked file(s)  */
  35. /*      prtNetArea()            makes human readable form of NET_AREA   */
  36. /*      setSpace()              goto specified "area"                   */
  37. /* #    realSetSpace()          does work of setSpace, others           */
  38. /* #    MSDOSparse()            parses a string for MSDOS filename      */
  39. /* #    fileType()              gets file type for MSDOS                */
  40. /*      sysGetSendFiles()       specify where to send files from        */
  41. /*      updFiletag()            updates a filetag                       */
  42. /*      sysRoomLeft()           how much room left in net recept area   */
  43. /* #    getSize()               gets size of a file                     */
  44. /*      sysSendFiles()          system dep stuff for sending files      */
  45. /* #    doSendWork()            does work of sysSendFiles()             */
  46. /*              BAUD HANDLER:                                           */
  47. /* #    check_CR()              scan input for carriage returns         */
  48. /*      Find_baud()             does flip flop search for baud          */
  49. /*      getNetBaud()            check for baud of network caller        */
  50. /*              CONSOLE HANDLING:                                       */
  51. /*      KBReady()               returns TRUE if a console char is ready */
  52. /*      mputChar()              Do our own for some Console output      */
  53. /*                                                                      */
  54. /*              # == local for this implementation only                 */
  55. /************************************************************************/
  56. #define NO_IDEA         0
  57. #define SINGLE_FILE     1
  58. #define IS_DIR          2
  59. #define AMB_FILE        3
  60. /************************************************************************/
  61. /*      Globals -- there shouldn't be anything here but statics and     */
  62. /*      externs.                                                        */
  63. /************************************************************************/
  64. /* These MUST be defined! */
  65. short ConDelay;
  66. char *R_W_ANY     = "rb+";
  67. char *READ_ANY    = "rb";
  68. char *READ_TEXT   = "ra";
  69. char *APPEND_TEXT = "aa";
  70. char *APPEND_ANY  = "ab";
  71. char *A_C_TEXT    = "ab";
  72. char *WRITE_TEXT  = "wa";
  73. char *W_R_ANY     = "wb+";
  74. char *WRITE_ANY   = "wb";
  75. static FILE *fileTags;                  /* For the file tags            */
  76.  
  77. int Jsystem(char *);
  78. void Do_Stack_Check(void);
  79.  
  80. char *rates[] =
  81.   {
  82.   "300",   "1200",  "2400",   "4800",    "9600",
  83.   "14400", "19200", "38400", "57600", "Unknown"
  84.  
  85.   };
  86. static short LastBaudIndex;
  87.  
  88. /* Here's the rest of the goo */
  89. extern logBuffer logBuf;         /* Log buffer of a person       */
  90. extern SListBase ResList;
  91. extern aRoom     roomBuf;
  92. extern MessageBuffer   msgBuf;
  93. extern CONFIG    cfg;            /* Lots an lots of variables    */
  94. extern char onConsole;                  /* Who's in control?!?          */
  95. extern char whichIO;                    /* CONSOLE or MODEM             */
  96. extern char anyEcho;
  97. extern char echo;
  98. extern FILE *upfd;
  99. extern char modStat;
  100. extern char echoChar;
  101. extern char haveCarrier;
  102. extern long netBytes;
  103. extern char outFlag;
  104. extern char *indexTable;
  105. void *ChPhrase(DirEntry *e, DirEntry *d);
  106. /************************************************************************/
  107. /* Section 3.4. AREAS:                                                  */
  108. /*   The model of Citadel includes a provision for "directory rooms."   */
  109. /* A directory room is defined as the ability to look in on some section*/
  110. /* of the host system's file section.  In order to avoid tying the      */
  111. /* directory structure of Citadel to any particular operating system, an*/
  112. /* "abstraction" has been implemented.  Each room that has been desig-  */
  113. /* nated as a directory will have an "area" associated with it.  This   */
  114. /* "area" is dependent on each implementation; access to "areas" is     */
  115. /* through routines located in this module.  Therefore, the abstract    */
  116. /* directory model of Citadel is in the main code modules, and should   */
  117. /* not require any changes from port to port.  The only changes neces-  */
  118. /* sary should be in this file (SYSDEP.C), where the porter must decide */
  119. /* upon and implement a mapping of how a directory room peeks in on his */
  120. /* or her file system.                                                  */
  121. /*   Basically, the routines are fairly simple in purpose.              */
  122. /*                                                                      */
  123. /*      "And if pigs had wings they could fly!"                         */
  124. /************************************************************************/
  125. char        ourHomeSpace[150];
  126. char MatchList[] = ".-_*?";
  127. /************************************************************************/
  128. /*      ValidDirFileName() validate a file name                         */
  129. /************************************************************************/
  130. char ValidDirFileName(char *ptr)
  131.   {
  132.   Do_Stack_Check();
  133.   while (*ptr)
  134.     {
  135.     if (isalpha(*ptr) || isdigit(*ptr) || strchr(MatchList, *ptr))
  136.     ++ptr;
  137.     else
  138.     return FALSE;
  139.  
  140.     }
  141.   return TRUE;
  142.  
  143.   }
  144. /************************************************************************/
  145. /*      RoomLeft() how much room left on this disk or whatever?         */
  146. /*      NB: Returns in K, not bytes!                                    */
  147. /************************************************************************/
  148. long RoomLeft(aRoom *room)
  149.   {
  150.   char *temp, dir[150];
  151.   long temp3, temp2;
  152.   long toReturn;
  153.   /* this should never happen, but just in case ... */
  154.   Do_Stack_Check();
  155.   if ((temp = FindDirName(room->rbArea)) == NULL)  return 0;
  156.   strCpy(dir, temp);
  157.   diskSpaceLeft(dir, &temp3, &temp2);
  158.   toReturn = temp2 / 1024l;
  159.   return toReturn;
  160.  
  161.   }
  162. /************************************************************************/
  163. /*      CitGetFileList() Get a list of files from the current "area"    */
  164. /*      Returns the # of files listed that fit the given mask           */
  165. /************************************************************************/
  166. static char *Phrase;
  167. #define ONE_DAY         86400L
  168. #define D_OFFSET        252460800L
  169. void CitGetFileList(char *mask, SListBase *list, long before, long after,
  170. char *phrase)
  171.   {
  172.   struct FileInfoBlock *FlBlock;
  173.   extern char     *monthTab[13];
  174.   char            *w, *work, *sp, again, buf[10];
  175.   DirEntry        *fp;
  176.   int             done;
  177.   long            time;
  178.   struct tm         *v;
  179.   Do_Stack_Check();
  180.   w = work = strdup(mask);
  181.   FlBlock = malloc(sizeof *FlBlock);
  182.   do
  183.     {
  184.     again = (sp = strchr(work, ' ')) != NULL;      /* space is separator */
  185.     if (again)
  186.       {
  187.       *sp = 0;
  188.  
  189.       }
  190.     /* Do all scanning for illegal requests here */
  191.     if (!ValidDirFileName(work))
  192.     continue;
  193.     for (done = dfind(FlBlock, work, 0); !done;
  194.     done = dnext(FlBlock))
  195.       {
  196.       /* format date to our standards */
  197.       /* DosToNormal(buf, FlBlock->ff_fdate);  */
  198.       time = D_OFFSET + (long)(ONE_DAY * FlBlock->fib_Date.ds_Days) +
  199.       (long)(FlBlock->fib_Date.ds_Minute * 60) +
  200.       (long)(FlBlock->fib_Date.ds_Tick / 50);
  201.       v = localtime(&time);
  202.       sPrintf(buf, "%d%s%02d", v->tm_year, monthTab[v->tm_mon+1],
  203.       v->tm_mday);
  204.       /* now read it so we can handle date specs */
  205.       ReadDate(buf, &time);
  206.       /* add to list iff dates inactive or we meet the specs */
  207.       if ((before != -1l && time > before) ||
  208.       (after  != -1l && time < after))
  209.       continue;
  210.       fp = (DirEntry *) GetDynamic(sizeof *fp);
  211.       fp->unambig = strdup(FlBlock->fib_FileName);
  212.       strCpy(fp->FileDate, buf);
  213.       fp->FileSize = FlBlock->fib_Size;
  214.       AddData(list, fp, NULL, TRUE);
  215.  
  216.       }
  217.     if (again) work = sp+1;
  218.  
  219.     }
  220.   while (again);
  221.   free(w);
  222.   free(FlBlock);
  223.   if (strLen(phrase) != 0)
  224.     {
  225.     Phrase = phrase;
  226.     StFileComSearch();      /* so's we can do phrase searches */
  227.     list->CheckIt = ChPhrase;   /* COVER YOUR EYES I'M CHEATING! */
  228.     KillData(list, list);
  229.     list->CheckIt = DirCheck;   /* COVER YOUR EYES I'M CHEATING! */
  230.     EndFileComment();
  231.  
  232.     }
  233.  
  234.   }
  235. /************************************************************************/
  236. /*      ChPhrase() does something to do with finding phrases in comments*/
  237. /************************************************************************/
  238. void *ChPhrase(DirEntry *e, DirEntry *d)
  239.   {
  240.   Do_Stack_Check();
  241.   if (FindFileComment(e->unambig, FALSE))
  242.     {
  243.     if (matchString(msgBuf.mbtext, Phrase, lbyte(msgBuf.mbtext))
  244.     == NULL) return d;
  245.  
  246.     }
  247.   else return d;
  248.   return NULL;
  249.  
  250.   }
  251. /************************************************************************/
  252. /*      getArea() get area to assign to a directory room from sysop     */
  253. /*      returns FALSE if problems or abort                              */
  254. /************************************************************************/
  255. char getArea(aRoom *roomData)
  256.   {
  257.   char dir[200];
  258.   SYS_FILE filename;
  259.   extern char *DirFileName;
  260.   extern SListBase DirBase;
  261.   Do_Stack_Check();
  262.   if (!goodArea("DIRNAM", dir))
  263.     {
  264.     return FALSE;
  265.  
  266.     }
  267.   makeSysName(filename, DirFileName, &cfg.roomArea);
  268.   upfd = safeopen(filename, WRITE_TEXT);
  269.   AddData(&DirBase, NtoStrInit(roomData->rbArea, dir, 0, FALSE),
  270.   WrtNtoStr, /* Kill duplicates */ TRUE);
  271.   fclose(upfd);
  272.   return TRUE;
  273.  
  274.   }
  275. /************************************************************************/
  276. /*      fileType() gets file type for MSDOS                             */
  277. /************************************************************************/
  278. fileType(char *theDir)
  279.   {
  280.   FILE *fd;
  281.   Do_Stack_Check();
  282.   if (strchr(theDir, '*') != NULL ||
  283.   strchr(theDir, '?') != NULL)
  284.     {
  285.     return AMB_FILE;
  286.  
  287.     }
  288.   if (realSetSpace(theDir))
  289.     {
  290.     homeSpace();
  291.     return IS_DIR;
  292.  
  293.     }
  294.   if ((fd = safeopen(theDir, READ_TEXT)) != NULL)
  295.     {
  296.     fclose(fd);
  297.     return SINGLE_FILE;
  298.  
  299.     }
  300.   return NO_IDEA;
  301.  
  302.   }
  303. /************************************************************************/
  304. /*      goodArea() Gets a valid path from the sysop. Drive should be    */
  305. /*                  set already.                                        */
  306. /************************************************************************/
  307. goodArea(char *prompt, char *dir)
  308.   {
  309.   int  c;
  310.   char dir_x[150];
  311.   Do_Stack_Check();
  312.   while (TRUE)
  313.     {
  314.     if (!getXString(prompt, dir_x, 149, "", ""))
  315.     return FALSE;
  316.     c = fileType(dir_x);
  317.     switch (c)
  318.       {
  319.       case IS_DIR:
  320.       strCpy(dir, dir_x);
  321.       return TRUE;
  322.       case NO_IDEA:
  323.       if (strLen(dir_x) != 0)
  324.         {
  325.         Output_Citadel_Message("DNTEXS",(long)dir_x,NULL,NULL);
  326.         if (getYesNo("CREATE"))
  327.           {
  328.           if (mkdir(dir_x) != 0)
  329.             {
  330.             Output_Citadel_Message("ERRDIR",(long)dir_x,NULL,NULL);
  331.             homeSpace();
  332.  
  333.             }
  334.           else
  335.             {
  336.             homeSpace();
  337.             strCpy(dir, dir_x);
  338.             return TRUE;
  339.  
  340.             }
  341.  
  342.           }
  343.  
  344.         }
  345.       else
  346.         {
  347.         strCpy(dir, dir_x);
  348.         return TRUE;
  349.  
  350.         }
  351.       break;
  352.       default:
  353.         Output_Citadel_Message("ERRNDR",(long)dir_x,NULL,NULL);
  354.       }
  355.  
  356.     }
  357.  
  358.   }
  359. /************************************************************************/
  360. /*      homeSpace() takes us home!                                      */
  361. /************************************************************************/
  362. void homeSpace()
  363.   {
  364.   Do_Stack_Check();
  365.   realSetSpace(ourHomeSpace);
  366.   }
  367. /************************************************************************/
  368. /*      netGetArea() Get area to store a file from networking           */
  369. /************************************************************************/
  370. netGetAreaV2(MenuId id,char *fn, struct fl_req *file_data, char ambiguous)
  371.   {
  372.   char goodname;
  373.   Do_Stack_Check();
  374.   if (!goodArea("DIRNSY", file_data->flArea.naDirname)) return FALSE;
  375.   if (!ambiguous)
  376.     {
  377.     realSetSpace(file_data->flArea.naDirname);
  378.     do
  379.       {
  380.       if (!getXString("FILNSY",file_data->filename, NAMESIZE, fn, fn))
  381.         {
  382.         homeSpace();
  383.         return FALSE;
  384.  
  385.         }
  386.       if (access(file_data->filename, 0) == 0)
  387.         {
  388.         Output_Citadel_Message("AREXTS",(long)file_data->filename,NULL,NULL);
  389.         goodname = SysopGetYesNo(id,"ISTHIS","THEPRM");
  390.  
  391.         }
  392.       else goodname = TRUE;
  393.  
  394.       }
  395.     while (!goodname);
  396.     homeSpace();
  397.  
  398.     }
  399.   else
  400.     {
  401.     Output_Citadel_Message("AMBFRS",NULL,NULL,NULL);
  402.     file_data->filename[0] = 0;
  403.     return FALSE;
  404.     }
  405.   return TRUE;
  406.  
  407.   }
  408. /************************************************************************/
  409. /*      prtNetArea() human readable form of a NET_AREA                  */
  410. /************************************************************************/
  411. char *prtNetArea(NET_AREA *netArea)
  412.   {
  413.   Do_Stack_Check();
  414.   return netArea->naDirname;
  415.  
  416.   }
  417. /************************************************************************/
  418. /*      dirString() a directory string                                                                          */
  419. /************************************************************************/
  420. void dirString(char *target, ROOM_AREA *area)
  421.   {
  422.   char *temp;
  423.   Do_Stack_Check();
  424.   if ((temp = FindDirName(*area)) != NULL)
  425.   strCpy(target, temp);
  426.   else strCpy(target, "ERROR");
  427.  
  428.   }
  429. /************************************************************************/
  430. /*      realSetSpace() does work of setSpace                            */
  431. /************************************************************************/
  432. char currentdir[150];
  433. char realSetSpace(char *dir)
  434.   {
  435.   extern FILE *netLog;
  436.   char result;
  437.   Do_Stack_Check();
  438.   if (cfg.BoolFlags.debug)
  439.     {
  440.     splitF(netLog,"Changing from %s\n",currentdir);
  441.     splitF(netLog,"To:%s\n",dir);
  442.     };
  443.   strcpy(currentdir,dir);
  444.   SpecialMessage(dir);
  445.   result = (char )(chdir(dir)== 0 );
  446.   return result;
  447.   }
  448. /************************************************************************/
  449. /*      FindDirName() finds the directory associated with some room     */
  450. /************************************************************************/
  451. char *FindDirName(int roomNo)
  452.   {
  453.   Do_Stack_Check();
  454.   return (char *)
  455.   SearchList(&DirBase, NtoStrInit(roomNo, "", 0, TRUE));
  456.  
  457.   }
  458. /************************************************************************/
  459. /*      setSpace() moves us to an area                                  */
  460. /************************************************************************/
  461. char setSpace(aRoom *roomData)
  462.   {
  463.   char   *temp;
  464.   extern SListBase DirBase;
  465.   Do_Stack_Check();
  466.   if ((temp = FindDirName(roomData->rbArea)) == NULL)
  467.     {
  468.     Output_Citadel_Message("ERRDRM",NULL,NULL,NULL);
  469.     return FALSE;
  470.  
  471.     }
  472.   if (!realSetSpace(temp))
  473.     {
  474.     Output_Citadel_Message("ERRDME",(long)temp,NULL,NULL);
  475.     return FALSE;
  476.  
  477.     }
  478.   return TRUE;
  479.  
  480.   }
  481. #ifdef READY
  482. /************************************************************************/
  483. /*      writeArea(x) prints the area associated with this room          */
  484. /************************************************************************/
  485. void writeArea(char rightNow, aRoom *roomData, char *buf)
  486.   {
  487.   Do_Stack_Check();
  488.   if (rightNow)
  489.   mPrintf("%s\n ", FindDirName(roomData->rbArea));
  490.   else
  491.     {
  492.     if (strLen(FindDirName(roomData->rbArea)) != 0)
  493.     sPrintf(buf, "'%s'", FindDirName(roomData->rbArea));
  494.     else
  495.     sPrintf(buf, "'%c:'", locDisk);
  496.  
  497.     }
  498.  
  499.   }
  500. #endif
  501. /************************************************************************/
  502. /*      sysGetSendFiles() where to find files to send to another system */
  503. /************************************************************************/
  504. char sysGetSendFilesV2(MenuId id,char *name, struct fl_send *sendWhat)
  505.   {
  506.   Do_Stack_Check();
  507.   strCpy(sendWhat->snArea.naDirname, name);
  508.   if (fileType(sendWhat->snArea.naDirname) == NO_IDEA)
  509.     {
  510.     if (SysopGetYesNo(id,NULL,"FILDIR"))
  511.     return TRUE;
  512.     return FALSE;
  513.  
  514.     }
  515.   return TRUE;
  516.  
  517.   }
  518. /************************************************************************/
  519. /*      CopyFile() copies a file                                        */
  520. /************************************************************************/
  521. char CopyFile(char *oldname, aRoom *roomData)
  522.   {
  523.   int len;
  524.   #ifdef NO_STAT
  525.   BPTR F_Lock;
  526.   struct FileInfoBlock *FIBlk;
  527.   char F_Ok;
  528.   LONG F_Status;
  529.   #else
  530.   struct stat buf;
  531.   #endif
  532.   char *temp;
  533.   char buffer[256];
  534.   char F_Node[32],F_Ext[32];
  535.   Do_Stack_Check();
  536.   if ((temp = FindDirName(roomData->rbArea)) == NULL)
  537.     {
  538.     Output_Citadel_Message("ERRDRM",NULL,NULL,NULL);
  539.     return FALSE;
  540.  
  541.     }
  542.   #ifdef NO_STAT
  543.   F_Ok = FALSE;
  544.   F_Lock = Lock(oldname,-2);
  545.   if (F_Lock != NULL)
  546.     {
  547.     FIBlk=(struct FileInfoBlock *)malloc(sizeof(struct FileInfoBlock));
  548.     if (FIBlk != NULL)
  549.       {
  550.       F_Status = Examine(F_Lock, FIBlk);
  551.       if (F_Status != 0)
  552.         {
  553.         if (FIBlk->fib_DirEntryType < 0)
  554.         F_Ok = TRUE;
  555.  
  556.         }
  557.       free(FIBlk);
  558.  
  559.       }
  560.     UnLock(F_Lock);
  561.  
  562.     }
  563.   if (!F_Ok)
  564.     {
  565.     Output_Citadel_Message("ISNCPY",(long)oldname,NULL,NULL);
  566.     return FALSE;
  567.  
  568.     }
  569.   #else
  570.   if (stat(oldname, &buf) != 0 || !(buf.st_mode & S_IFREG))
  571.     {
  572.     Output_Citadel_Message("ISNCPY",(long) oldname,NULL,NULL);
  573.     return FALSE;
  574.  
  575.     }
  576.   #endif
  577.   sPrintf(buffer, "copy >NIL: %s %s", oldname, temp);
  578.   Jsystem(buffer);
  579.   strsfn(oldname,NULL,NULL,F_Node,F_Ext);
  580.   temp = FindDirName(roomData->rbArea);
  581.   sPrintf(oldname, "%s%c%s", F_Node,(F_Ext[0] != 0) ? '.' : '\0', F_Ext);
  582.   len = strlen(temp);
  583.   if ( temp[len-1] == ':' || temp[len-1] == '/' )
  584.     {
  585.     sPrintf(buffer, "%s%s",temp,oldname);
  586.     }
  587.   else    sPrintf(buffer, "%s/%s",temp,oldname);
  588.   return ((char)(access(buffer, 0) == 0));
  589.  
  590.   }
  591. /************************************************************************/
  592. /*      MoveFile() move a file to a new name and location               */
  593. /************************************************************************/
  594. void MoveFile(char *oldname, char *newname)
  595.   {
  596.   char buffer[100];
  597.   FILE *infd, *outfd;
  598.   int s;
  599.   Do_Stack_Check();
  600.   if (toUpper(*oldname) == toUpper(*newname))
  601.     {
  602.     rename(oldname, newname);
  603.     if (access(newname, 0) == 0) return;
  604.  
  605.     }
  606.   sPrintf(buffer, "copy >NIL: %s %s", oldname, newname);
  607.   Jsystem(buffer);
  608.   if (access(newname, 0) == 0)
  609.     {
  610.     unlink(oldname);
  611.  
  612.     }
  613.   else
  614.     {
  615.     if ((infd = safeopen(oldname, READ_ANY)) == NULL) return;
  616.     if ((outfd = safeopen(newname, WRITE_ANY)) == NULL)
  617.       {
  618.       fclose(infd);
  619.       return;
  620.  
  621.       }
  622.     while ((s = fread(buffer, sizeof buffer, 1, infd)) > 0)
  623.     fwrite(buffer, s, 1, outfd);
  624.     fclose(infd);
  625.     fclose(outfd);
  626.     unlink(oldname);
  627.  
  628.     }
  629.  
  630.   }
  631. /************************************************************************/
  632. /*      sysRoomLeft() how much room left in net recept area             */
  633. /************************************************************************/
  634. long sysRoomLeft()
  635.   {
  636.   long temp, temp2, temp3;
  637.   Do_Stack_Check();
  638.   temp = (long) ( (long) cfg.sizeArea * 1024);
  639.   netBytes = 0l;
  640.   doSendWork(ALL_FILES, getSize);
  641.   diskSpaceLeft(NULL, &temp3, &temp2);
  642.   return (minimum(temp - netBytes, temp2));
  643.  
  644.   }
  645. /************************************************************************/
  646. /*      sysSendFiles() system dep stuff for sending files               */
  647. /************************************************************************/
  648. void sysSendFiles(struct fl_send *sendWhat)
  649.   {
  650.   char   temp[100], *last;
  651.   label  mask;
  652.   Do_Stack_Check();
  653.   strCpy(temp, sendWhat->snArea.naDirname);
  654.   switch (fileType(sendWhat->snArea.naDirname))
  655.     {
  656.     case IS_DIR:
  657.     strCpy(mask, "*");
  658.     break;
  659.     case SINGLE_FILE:
  660.     case AMB_FILE:
  661.     if ((last = strrchr(temp, '/')) == NULL &&
  662.     (last = strrchr(temp, ':')) == NULL)
  663.       {
  664.       strCpy(mask, temp);
  665.       temp[0] = 0;
  666.  
  667.       }
  668.     else
  669.       {
  670.       strCpy(mask, last + 1);
  671.       if (last != temp && *last != ':')
  672.       *last = 0;
  673.       else
  674.       *(last + 1) = 0;
  675.  
  676.       }
  677.     break;
  678.     case NO_IDEA:
  679.     default:
  680.     sPrintf(temp, "Couldn't do anything with '%s'.",
  681.     sendWhat->snArea.naDirname);
  682.     netResult(temp);
  683.     return;
  684.  
  685.     }
  686.   if (!realSetSpace(temp))
  687.     {
  688.     sPrintf(msgBuf.mbtext, "Send file didn't know what to do with %s.",
  689.     temp);
  690.     netResult(msgBuf.mbtext);
  691.  
  692.     }
  693.   else
  694.   doSendWork(mask, netSendFile);
  695.   homeSpace();
  696.  
  697.   }
  698. /************************************************************************/
  699. /*      doSendWork() does work of sysSendFiles()                        */
  700. /************************************************************************/
  701. void doSendWork(char *filename, void (*fn)(DirEntry *f))
  702.   {
  703.   Do_Stack_Check();
  704.   wildCard(fn, filename, FALSE, "", FALSE);
  705.  
  706.   }
  707. /************************************************************************/
  708. /*      DoDomainDirectory() work on a domain directory                  */
  709. /************************************************************************/
  710. void DoDomainDirectory(int i, char kill)
  711.   {
  712.   char num[8];
  713.   DOMAIN_FILE name;
  714.   Do_Stack_Check();
  715.   sPrintf(num, "%d", i);
  716.   makeSysName(name, num, &cfg.domainArea);
  717.   if (kill) rmdir(name);
  718.   else      mkdir(name);
  719.  
  720.   }
  721. /************************************************************************/
  722. /* Section 3.5. BAUD HANDLER:                                           */
  723. /*    The code in here has to discover what baud rate the caller is at. */
  724. /* For some computers, this should be ridiculously easy.                */
  725. /************************************************************************/
  726. #define NO_GOOD         0
  727. #define CR_CAUGHT       1
  728. #define NET_CAUGHT      2
  729. #define STROLL_CAUGHT   3
  730. /************************************************************************/
  731. /*      check_CR() Checks for CRs from the data port for half a second. */
  732. /************************************************************************/
  733. static short crcnt;
  734. static short timer1,timer2;
  735. char check_CR()
  736.   {
  737.   extern FILE *netLog;
  738.   struct timePacket ff;
  739.   int c=0;
  740.   int  clcnt=0;
  741.   char clast[8];  /* debug: last eight characters */
  742.   memset(clast,0,8);
  743.   Do_Stack_Check();
  744.   setTimer(&ff);
  745.   while (milliTimeSince(&ff) < timer1 )
  746.     {
  747.     if (MIReady())
  748.       {
  749.       if( c != 13 )crcnt = 0;
  750.       clast[clcnt & 0x07] = c = inp();
  751.       clcnt++;
  752.       switch (c)
  753.         {
  754.         case 27: return CR_CAUGHT;break;  /* one escape, or two CRs */
  755.         case 13:                          /* cr from user?, must have 2 */
  756.         if( ++crcnt >1)
  757.           {
  758.           return CR_CAUGHT;
  759.           };
  760.         break;
  761.         case 7:
  762.         if (cfg.BoolFlags.netParticipant)
  763.           {
  764.           if (receive(1) == 13)
  765.             {
  766.             crcnt = 1;
  767.             if (receive(1) == 69)
  768.               {
  769.               return NET_CAUGHT;
  770.               };
  771.             };
  772.           };
  773.         break;
  774.         case 68:
  775.         if (receive(1) == 79)
  776.           {
  777.           if (receive(1) == 35)
  778.             {
  779.             return STROLL_CAUGHT;
  780.             };
  781.           };
  782.         break;
  783.         default:
  784.         if (clcnt > 0 && cfg.BoolFlags.debug)
  785.           {
  786.           splitF(netLog,"%x %x %x %x\n ",clast[0],clast[1],clast[2],clast[3]);
  787.           splitF(netLog,"%x %x %x %x\n ",clast[4],clast[5],clast[6],clast[7]);
  788.           };
  789.         };
  790.       };
  791.     };
  792.   return NO_GOOD;
  793.   }
  794. /************************************************************************/
  795. /*      Find_Baud() Finds the baud from sysop and user supplied data.   */
  796. /************************************************************************/
  797. char Find_baud(char **whatRate)
  798.   {
  799.   char noGood = NO_GOOD;
  800.   int  Time = 0;
  801.   long  baudRunner;                    /* Only try for 60 seconds      */
  802.   char flag;
  803.   extern FILE *netLog;
  804.   extern long byteRate;
  805.   crcnt = 0;
  806.   Do_Stack_Check();
  807.   *whatRate = rates[9];  /* default to unknown */
  808.   flag = FALSE;
  809.   if ((baudRunner = (long)getModemId()) != ERROR)
  810.     {
  811.     CitadelBaudRate(baudRunner, "Find_baud");
  812.     flag = TRUE;
  813.     if (cfg.BoolFlags.debug) splitF(netLog, "getModemId = %d\n",baudRunner);
  814.     };
  815.   if (cfg.DepData.LockPort >= 0 && !flag)  /* if serial port locked, use it */
  816.     {
  817.     baudRunner = cfg.DepData.LockPort;
  818.     flag = TRUE;
  819.     if (cfg.BoolFlags.debug) splitF(netLog, "LockPort Forced = %d\n",baudRunner);
  820.     };
  821.   pause(10);                    /* To clear line noise and eat banner */
  822.   while (MIReady())   inp();   /* eat noise and banners        */
  823.   if( cfg.DepData.LockPort >= 0 || flag )
  824.     {
  825.     timer1 = 50;               /* time spent looking for User/Net session */
  826.     timer2 =  4;               /* number of autobaud attempts */
  827.     }
  828.   else
  829.     {
  830.     timer1 = 75;                /* time spent looking for User/Net session */
  831.     timer2 = (cfg.sysBaud+1)*3; /* autobaud attempts, try 3 attempts */
  832.     baudRunner = 0;
  833.     };
  834.   while (gotCarrier() && noGood == NO_GOOD &&  (Time < timer2))
  835.     {
  836.     Time++;
  837.     if( !flag )
  838.       {
  839.       CitadelBaudRate(baudRunner,"Find_baud");
  840.       };
  841.     noGood = check_CR();
  842.     if (noGood == NO_GOOD && !flag)
  843.       {
  844.       if( baudRunner++ > cfg.sysBaud )baudRunner = 0;
  845.       };
  846.     };
  847.   if( noGood == NO_GOOD && !flag )
  848.     {
  849.     baudRunner = cfg.sysBaud;
  850.     if( !flag ) CitadelBaudRate(baudRunner, "Find_baud");
  851.     };
  852.   LastBaudIndex = baudRunner;
  853.   *whatRate = rates[baudRunner];
  854.   byteRate =  (atol(rates[baudRunner]) ) / 10L;
  855.   if (cfg.BoolFlags.debug) splitF(netLog, "Time:%d Baud:%s\n",Time,*whatRate);
  856.   if (noGood == NET_CAUGHT)
  857.     {
  858.     netController(0, 0, NO_NETS, ANY_CALL, 0);
  859.     if (cfg.BoolFlags.debug) splitF(netLog, "Baud -%s-->Net_Caught\n",*whatRate);
  860.     return FALSE;       /* pretend nothing happened */
  861.  
  862.     }
  863.   if (noGood == STROLL_CAUGHT)
  864.     {
  865.     StrollIt();
  866.     if (cfg.BoolFlags.debug) splitF(netLog, "Baud -%s-->STROLL_Caught\n",*whatRate);
  867.     return FALSE;       /* pretend nothing happened */
  868.  
  869.     }
  870.   if (cfg.BoolFlags.debug) splitF(netLog, "Baud-%s-->other\n",*whatRate);
  871.   return (char)(noGood == CR_CAUGHT || flag); /* return TRUE if USER */
  872.  
  873.   }
  874. /************************************************************************/
  875. /*      getModemId() Try to read baud id from modem                     */
  876. /************************************************************************/
  877. #define BA_BUF_SIZE     50
  878. int getModemId()
  879.   {
  880.   char c, buffer[BA_BUF_SIZE];         /* Hopefully, overkill */
  881.   extern FILE *netLog;
  882.   struct timePacket ff;
  883.   int i;
  884.   UNS_16 *j;
  885.   extern char ResultCodesAvailable;
  886.   Do_Stack_Check();
  887.   if (!ResultCodesAvailable) return ERROR;
  888.   setTimer(&ff);
  889.   i = 0;
  890.   while (timeSince(&ff) < 5l)
  891.     {
  892.     if (MIReady())
  893.       {
  894.       if ((c = inp()) == '\r')
  895.         {
  896.         buffer[i] = 0;
  897.         if (cfg.BoolFlags.debug) splitF(netLog, "Modem text -%s-\n",buffer);
  898.         j = (int *) SearchList(&ResList, buffer);
  899.         if (j != NULL)
  900.           {
  901.           switch (*j)
  902.             {
  903.             case R_300:
  904.             case R_1200:
  905.             case R_2400:
  906.             case R_4800:
  907.             case R_9600:
  908.             case R_14400:
  909.             case R_19200:
  910.             case R_38400:
  911.             case R_57600:
  912.             return (int)*j;
  913.             default:
  914.             break;
  915.  
  916.             }
  917.           i = 0;
  918.  
  919.           }
  920.         else i = 0;
  921.  
  922.         }
  923.       else
  924.         {
  925.         if (c != '\n')
  926.           {
  927.           buffer[i++] = c;
  928.  
  929.           }
  930.         if (i >= BA_BUF_SIZE - 4)
  931.           {
  932.           /* Fudge factor */
  933.           i = 0;
  934.  
  935.           }
  936.  
  937.         }
  938.  
  939.       }
  940.  
  941.     }
  942.   buffer[i] = 0;      /* debug for now */
  943.   if (cfg.BoolFlags.debug) splitF(netLog, "FAILURE:GetModId=-%s-", buffer);
  944.   return ERROR;
  945.  
  946.   }
  947. /************************************************************************/
  948. /*      getNetBaud()  gets baud of network caller -- refer to SysDep.doc*/
  949. /************************************************************************/
  950. char getNetBaud()
  951.   {
  952.   extern FILE *netLog;
  953.   long   Time, baudRunner;
  954.   extern long byteRate;
  955.   char        found = FALSE, notFinished;
  956.   extern char inNet;
  957.   Do_Stack_Check();
  958.   /* If anytime answer, then we already have baud rate */
  959.   if (inNet == ANY_CALL || inNet == STROLL_CALL)
  960.     {
  961.     found      = TRUE;
  962.     baudRunner = LastBaudIndex;
  963.  
  964.     }
  965.   else if (GetFirst(&ResList))
  966.     {
  967.     if ((baudRunner = getModemId()) != ERROR)
  968.       {
  969.       found = TRUE;
  970.  
  971.       }
  972.  
  973.     }
  974.   pause(10);         /* Pause a  second */
  975.   if (found)
  976.     {
  977.     CitadelBaudRate(baudRunner, "getNetBaud");
  978.     byteRate = atol(rates[baudRunner]) / 10L;
  979.     for (Time = 0; gotCarrier() && Time < 25; Time++)
  980.       {
  981.       if (check_for_init(FALSE)) return TRUE;
  982.       if (cfg.BoolFlags.debug) splitF(netLog, "tick(%d). ",Time);
  983.  
  984.       }
  985.     if (gotCarrier())
  986.       {
  987.       outFlag = IMPERVIOUS;
  988.       Output_Citadel_Message("LATERN",timeLeft(),NULL,NULL);
  989.  
  990.       }
  991.  
  992.     }
  993.   else
  994.     {
  995.     while (MIReady())   inp();          /* Clear garbage        */
  996.     for (Time = 0; gotCarrier() && Time < 25; Time++)
  997.       {
  998.       for (notFinished = TRUE, baudRunner = 0;
  999.       gotCarrier() && notFinished;)
  1000.         {
  1001.         byteRate = atol(rates[baudRunner]) / 10L;
  1002.         CitadelBaudRate(baudRunner, "getNetBaud");
  1003.         if (check_for_init(FALSE)) return TRUE;  /* get connection */
  1004.         if (cfg.BoolFlags.debug) splitF(netLog, "Tock.\n");
  1005.         notFinished = !(baudRunner == cfg.sysBaud);
  1006.         baudRunner++;
  1007.  
  1008.         }
  1009.  
  1010.       }
  1011.     if (gotCarrier())
  1012.       {
  1013.       outFlag = IMPERVIOUS;
  1014.       for (baudRunner = cfg.sysBaud; baudRunner > -1; baudRunner--)
  1015.         {
  1016.         CitadelBaudRate(baudRunner, "getNetBaud");
  1017.         Output_Citadel_Message("LATERN",timeLeft(),NULL,NULL);
  1018.         }
  1019.       outFlag = OUTOK;
  1020.  
  1021.       }
  1022.  
  1023.     }
  1024.   if (!gotCarrier()) splitF(netLog, "GetNetBaud:Lost carrier\n");
  1025.   killConnection();
  1026.   return FALSE;
  1027.  
  1028.   }
  1029. /************************************************************************/
  1030. /* Section 3.3. CONSOLE HANDLING:                                       */
  1031. /*    These functions are responsible for handling console I/O.         */
  1032. /************************************************************************/
  1033. /************************************************************************/
  1034. /*      mputChar()                                                      */
  1035. /************************************************************************/
  1036.  
  1037. int ConPutChar(char myChar);
  1038.  
  1039. void mputChar(char c)
  1040.   {
  1041.   extern char ChatMode;
  1042.   Do_Stack_Check();
  1043.   if ((c == '\0') || (c == BELL && cfg.BoolFlags.noChat && !onConsole))
  1044.   return;
  1045.   if (!(whichIO == CONSOLE || onConsole) && !anyEcho)
  1046.   return;
  1047.   if (c != ESC &&       (echo == BOTH ||
  1048.   (whichIO == CONSOLE && (echo != NEITHER || echoChar))))
  1049.     {
  1050.     ConPutChar(c);
  1051.  
  1052.     }
  1053.   if (onConsole && !ChatMode && ConDelay > 0) pause(ConDelay);
  1054.  
  1055.   }
  1056. /************************************************************************/
  1057. /* 3.11. File Comment handling                                          */
  1058. /*   These four functions handle file comments.  In DOS, there is no    */
  1059. /* built-in way to keep file comments; therefore, we keep a file in     */
  1060. /* each subdirectory named FILEDIR.TXT which contains the file comments.*/
  1061. /************************************************************************/
  1062. static FILE *fileTags;                  /* For the file tags            */
  1063. static char *flDir = "filedir.txt";
  1064. static char tagFound = FALSE;
  1065. /************************************************************************/
  1066. /*      StFileComSearch() Start File Comment search: see SYSDEP.DOC.    */
  1067. /************************************************************************/
  1068. int StFileComSearch()
  1069.   {
  1070.   Do_Stack_Check();
  1071.   fileTags = safeopen(flDir, READ_TEXT);
  1072.   tagFound = TRUE;
  1073.   return TRUE;
  1074.  
  1075.   }
  1076. /************************************************************************/
  1077. /*      FindFileComment() find file comment for file: see SYSDEP.DOC.   */
  1078. /************************************************************************/
  1079. int FindFileComment(char *fileName, char extraneous)
  1080.   {
  1081.   char *c, Chatter = FALSE;
  1082.   int Last;
  1083.   /* Check to see if already in buffer */
  1084.   Do_Stack_Check();
  1085.   if (specCmpU(fileName, msgBuf.mbtext) == SAMESTRING) return TRUE;
  1086.   /*
  1087.   * No. If last search was successful, then we have to get the next
  1088.   * line right now.
  1089.   */
  1090.   if (tagFound && fileTags != NULL)
  1091.     {
  1092.     do
  1093.       {
  1094.       if ((c = fgets(msgBuf.mbtext, MAXTEXT-10, fileTags)) == NULL)
  1095.       break;
  1096.       if (msgBuf.mbtext[0] == ';')
  1097.       if (extraneous)
  1098.         {
  1099.         mFormat(msgBuf.mbtext + 1);
  1100.         Last = strLen(msgBuf.mbtext + 1);       /* finicky check */
  1101.         Chatter = TRUE;
  1102.  
  1103.         }
  1104.  
  1105.       }
  1106.     while (msgBuf.mbtext[0] == ';');
  1107.  
  1108.     }
  1109.   if (Chatter && Last > 1)/* need this for ";" stuff -- allows normal   */
  1110.   doCR();               /* formatting without blank lines.              */
  1111.   tagFound = FALSE;
  1112.   if (fileTags != NULL)
  1113.     {
  1114.     while (c != NULL && specCmpU(fileName, msgBuf.mbtext) > SAMESTRING)
  1115.       {
  1116.       do
  1117.         {
  1118.         if ((c=fgets(msgBuf.mbtext, MAXTEXT-10, fileTags)) == NULL)
  1119.         break;
  1120.         if (msgBuf.mbtext[0] == ';')
  1121.         if (extraneous)
  1122.           {
  1123.           mFormat(msgBuf.mbtext + 1);
  1124.           doCR();
  1125.  
  1126.           }
  1127.  
  1128.         }
  1129.       while (msgBuf.mbtext[0] == ';');
  1130.  
  1131.       }
  1132.     if (c != NULL)
  1133.     tagFound = (specCmpU(fileName, msgBuf.mbtext) == SAMESTRING);
  1134.  
  1135.     }
  1136.   return ((int)tagFound);
  1137.  
  1138.   }
  1139. /************************************************************************/
  1140. /*      EndFileComment() end session of reading file comments.          */
  1141. /************************************************************************/
  1142. void EndFileComment()
  1143.   {
  1144.   Do_Stack_Check();
  1145.   if (fileTags != NULL) fclose(fileTags);
  1146.   fileTags = NULL;
  1147.  
  1148.   }
  1149. /************************************************************************/
  1150. /*      updFiletag()  updates a file tag                                */
  1151. /************************************************************************/
  1152. void updFiletag(char *fileName, char *desc)
  1153.   {
  1154.   FILE        *updFd, *temp;
  1155.   char        *line, *l2, *c;
  1156.   static char *tmpName = "a45u8a7.$$$",
  1157.   *format  = "%s %s\n";
  1158.   Do_Stack_Check();
  1159.   if ((updFd = safeopen(flDir, READ_TEXT)) == NULL)
  1160.     {
  1161.     if ((updFd = safeopen(flDir, WRITE_TEXT)) == NULL)
  1162.       Output_Citadel_Message("UNKWNP",(long)flDir,NULL,NULL);
  1163.     else
  1164.       {
  1165.       fprintf(updFd, format, fileName, desc);
  1166.       fclose(updFd);
  1167.  
  1168.       }
  1169.     return;
  1170.  
  1171.     }
  1172.   else
  1173.     {
  1174.     line = strdup(msgBuf.mbtext);
  1175.     l2 = strdup(desc);          /* because msgBuf.mbtext is desc */
  1176.     temp = safeopen(tmpName, WRITE_TEXT);
  1177.     msgBuf.mbtext[0] = 0;
  1178.     while ((c=fgets(msgBuf.mbtext, MAXTEXT, updFd)) != NULL)
  1179.       {
  1180.       if (msgBuf.mbtext[0] != ';')
  1181.       if (specCmpU(fileName, msgBuf.mbtext) <= SAMESTRING) break;
  1182.       fprintf(temp, "%s", msgBuf.mbtext);
  1183.  
  1184.       }
  1185.     fprintf(temp, format, fileName, l2);
  1186.     if (c != NULL && specCmpU(fileName, msgBuf.mbtext) != SAMESTRING)
  1187.     fprintf(temp, "%s", msgBuf.mbtext);
  1188.     while ((c=fgets(msgBuf.mbtext, MAXTEXT, updFd)) != NULL)
  1189.     fprintf(temp, "%s", msgBuf.mbtext);
  1190.     fclose(updFd);
  1191.     fclose(temp);
  1192.     unlink(flDir);
  1193.     rename(tmpName, flDir);
  1194.     strCpy(msgBuf.mbtext, line);
  1195.     free(line);
  1196.     free(l2);
  1197.  
  1198.     }
  1199.  
  1200.   }
  1201.